package com.chuangke.security.authorization;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authorization.AuthorizationDecision;
import org.springframework.security.authorization.AuthorizationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.access.intercept.RequestAuthorizationContext;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;

import com.chuangke.admin.entity.SysMenu;
import com.chuangke.admin.entity.SysRoleMenu;
import com.chuangke.admin.entity.SysUser;
import com.chuangke.admin.entity.SysUserRole;
import com.chuangke.admin.service.SysMenuService;
import com.chuangke.admin.service.SysRoleMenuService;
import com.chuangke.admin.service.SysUserRoleService;
import com.chuangke.security.userdetails.JwtUserDetails;

import cn.hutool.core.util.StrUtil;

/**
 * 
 * @author admin
 *
 */
@Component
public class CommonAuthorizationManager implements AuthorizationManager<RequestAuthorizationContext> {

	@Autowired
	private SysMenuService sysMenuService;
	@Autowired
	private SysRoleMenuService sysRoleMenuService;
	@Autowired
	private SysUserRoleService sysUserRoleService;

	private final AntPathMatcher antPathMatcher = new AntPathMatcher();

	@Override
	public AuthorizationDecision check(Supplier<Authentication> authenticationSupplier,
			RequestAuthorizationContext requestAuthorizationContext) {
		// 当前用户的权限信息 比如角色
//		Collection<? extends GrantedAuthority> authorities = authenticationSupplier.get().getAuthorities();

		Authentication authentication = authenticationSupplier.get();
		
		if(authentication.getPrincipal() instanceof String) {
			//没有登录，匿名用户
			return new AuthorizationDecision(false);
		}
		
		JwtUserDetails userDetail = (JwtUserDetails) authentication.getPrincipal();
		SysUser user = userDetail.getUser();

		// 当前请求上下文
		// 我们可以获取携带的参数
//		Map<String, String> variables = requestAuthorizationContext.getVariables();

		// 我们可以获取原始request对象
		HttpServletRequest request = requestAuthorizationContext.getRequest();
		List<String> authRoleList = getAuthRoleList(request);

		if (CollectionUtils.isEmpty(authRoleList)) {
			//没有加入权限控制，登录即可访问
			return new AuthorizationDecision(true);
		}

		List<String> userRoleList = sysUserRoleService.findAll().get(user.getId()).stream().map(SysUserRole::getRoleId)
				.collect(Collectors.toList());

		userRoleList.retainAll(authRoleList);

		if (CollectionUtils.isEmpty(authRoleList)) {
			return new AuthorizationDecision(false);
		}

		boolean isGranted = true;
		return new AuthorizationDecision(isGranted);
	}

	/**
	 * 获取访问地址的授权角色
	 * 
	 * @param request
	 * @return
	 */
	private List<String> getAuthRoleList(HttpServletRequest request) {
		String requestURI = request.getRequestURI();
		List<SysMenu> allMenu = sysMenuService.findList();

		List<String> roleIdList = new ArrayList<>();
		for (SysMenu menu : allMenu) {
			if(StrUtil.isBlank(menu.getUrl())) {
				continue ;
			}
			if (!antPathMatcher.match(menu.getUrl(), requestURI)) {
				continue;
			}

			roleIdList.addAll(sysRoleMenuService.findByMenuId(menu.getId()).stream().map(SysRoleMenu::getRoleId)
					.collect(Collectors.toList()));
		}
		return roleIdList;
	}
}
